/** Object
**
** Base class of objects passed to RenderOneFrame
**
** Note: If your game objects have these fields, use them instead. Alternatively,
** put a member variable in here which points to one of your objects.
**
** @version: $Id: Object.h 154 2011-03-11 01:43:59Z shoutingchief@gmail.com $
*/
#pragma once

#include <d3dx9.h>
#include <vector>


/****************************************************
**************************\
*                                Object class                                  *
\******************************************************************************/
class Object
{
	friend class Renderer;

protected:
	/*****************************************************\
	* Structure to hold material and texture information  *
	* embedded in .X file                                 *
	\*****************************************************/
	struct MESHMATERIAL
	{
		D3DMATERIAL9*		m_pMaterial;	// pointer to material for this subset
		IDirect3DTexture9*	m_pTexture;		// pointer to texture for this subset
	};

	/* Array of MESHMATERIALs */
	typedef std::vector<MESHMATERIAL*> MESHMATERIALS;


	/*****************************************************\
	* Member variables                                    *
	\*****************************************************/
	D3DXVECTOR3			m_vPosition;		// location in world coordinates
	ID3DXMesh*			m_pMesh;			// optimized polygon mesh
	MESHMATERIALS		m_vMaterials;		// materials and textures for each subset of the mesh
	D3DXMATRIX			m_mWorld;			// WORLD transform: transforms OBJECT coordinates into WORLD coordinates
	D3DXVECTOR3			m_vOrigin;			// where is it relative to its own center?
	float				m_fBoundingRadius;	// radius of bounding sphere
	float				m_fScale;			// desired scale factor


	/*****************************************************\
	* Update WORLD transform so object drawn correctly    *
	\*****************************************************/
	virtual void UpdateWorldTransform();

public:
	/*****************************************************\
	* Object constructor                                  *
	\*****************************************************/
	Object(const D3DXVECTOR3& cvPosition, const float cfScale = 1.0f);

	/*****************************************************\
	* Destructor                                          *
	\*****************************************************/
	virtual ~Object();

	/*****************************************************\
	* Update each frame                                   *
	\*****************************************************/
	virtual bool Update(const double cdDeltaTime);

	/*****************************************************\
	* Set current position in space                       *
	\*****************************************************/
	virtual void SetPosition(const D3DXVECTOR3& cvPosition);

	/*****************************************************\
	* Set current display scale factor                    *
	\*****************************************************/
	virtual void SetScale(const float cfScale);

	/*****************************************************\
	* Set WORLD transform                                 *
	\*****************************************************/
	virtual void SetWorldTransform(const D3DXMATRIX mWorld);

	/*****************************************************\
	* Get pointer to mesh object                          *
	\*****************************************************/
	ID3DXMesh* GetMesh();

	/*****************************************************\
	* Get bounding radius: radius of the bounding sphere  *
	\*****************************************************/
	float GetBoundingRadius();

	/*****************************************************\
	* Draw this object                                    *
	\*****************************************************/
	virtual void Render();

	/*****************************************************\
	* Add Material: put [material,texture] in list        *
	\*****************************************************/
	void AddMaterial(D3DMATERIAL9* pMaterial, IDirect3DTexture9* pTexture);

	/*****************************************************\
	* Get Material: get [material,texture] for mesh       *
	\*****************************************************/
	void GetMaterial(unsigned n, D3DMATERIAL9** ppMaterial, IDirect3DTexture9** ppTexture);
};


/*****************************************************\
* List of objects                                     *
\*****************************************************/
typedef std::vector<Object*> ObjectList;
#define InsertObject(o, L)		L.push_back(o)
